package com.example.user.customviewdemo.drawing.range;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.RegionIterator;
import android.util.AttributeSet;
import android.view.View;

/**
 * 想要跟别人不一样，你就要跟别人不一样。----- Harvic
 * Created by user on 2016/4/22.
 * 用于绘制区域
 */
public class MyRegionView extends View {

    public MyRegionView(Context context) {
        super(context);
    }

    public MyRegionView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyRegionView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GRAY);

        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10);

       /* new Region();
        new Region(Region region)
        new Region(Rect r)   这些都是Region的构造函数    */
        Region region = new Region(10, 10, 100, 100);//也是以矩形构造Region
        drawRegion(canvas, region, paint);

        /*region有一系列的set方法来构造Region  region每次set了之后就会把之前的覆盖掉
        set(Region region)：利用新的区域值来替换原来的区域
        set(Rect r)：利用矩形所代表的区域替换原来的区域
        set(int left, int top, int right, int bottom)：同样，根据矩形的两个点构造出矩形区域来替换原来的区域值
        setPath(Path path, Region clip)：可以构造不规则区域，根据路径的区域与某区域的交集，构造出新区域，这个后面具体讲解*/
        region.set(200, 10, 300, 100);//region每次set了之后就会把之前的覆盖掉，成为一个新的region
        drawRegion(canvas, region, paint);

        /************构造一个椭圆region***************/
        Path path = new Path();
        RectF ovalRectF = new RectF(500, 10, 700, 210);
        path.addOval(ovalRectF, Direction.CW);
        region.setPath(path, new Region(500, 10, 700, 210));
        drawRegion(canvas, region, paint);

        /*****************************************区域的合并交叉等操作*******************************************/
        /**
         * 总结：
         * 无论是区域还是矩形，都会涉及到与另一个区域的一些操作，比如取交集、取并集等，涉及到的函数有：

         public final boolean union(Rect r)
         public boolean op(Rect r, Op op) {
         public boolean op(int left, int top, int right, int bottom, Op op)
         public boolean op(Region region, Op op)
         public boolean op(Rect rect, Region region, Op op)

         除了Union(Rect r)是指定合并操作以外，其它四个op（）构造函数，都是指定与另一个区域的操作。其中最重要的指定Op的参数，Op的参数有下面四个：

         假设用region1  去组合region2
         public enum Op {
         DIFFERENCE(0), //最终区域为region1 与 region2不同的区域
         INTERSECT(1), // 最终区域为region1 与 region2相交的区域
         UNION(2),      //最终区域为region1 与 region2组合一起的区域
         XOR(3),        //最终区域为region1 与 region2相交之外的区域
         REVERSE_DIFFERENCE(4), //最终区域为region2 与 region1不同的区域
         REPLACE(5); //最终区域为为region2的区域
         }
         */

        /**************取region1交集于region2********************/
        Rect rect1 = new Rect(100, 250, 400, 350);
        Region region1 = new Region(rect1);

        Rect rect2 = new Rect(200, 150, 300, 450);
        Region region2 = new Region(rect2);

        canvas.drawRect(rect1, paint);
        canvas.drawRect(rect2, paint);

        region1.op(region2, Region.Op.REVERSE_DIFFERENCE);
        paint.setColor(Color.GREEN);
        paint.setStyle(Paint.Style.FILL);
        drawRegion(canvas, region1, paint);


       /* // 几个判断方法
                    public native boolean isEmpty();//判断该区域是否为空
                    public native boolean isRect(); //是否是一个矩阵
                    public native boolean isComplex();//是否是多个矩阵组合

            //一系列的getBound方法，返回一个Region的边界
                    public Rect getBounds ()
                    public boolean getBounds (Rect r)
                    public Path getBoundaryPath ()
                    public boolean getBoundaryPath (Path path)

            //一系列的判断是否包含某点 和是否相交
                    public native boolean contains ( int x, int y);//是否包含某点
                    public boolean quickContains (Rect r)   //是否包含某矩形
                    public native boolean quickContains ( int left, int top, int right,
                    int bottom) //是否没有包含某矩阵形
                    public boolean quickReject (Rect r) //是否没和该矩形相交
                    public native boolean quickReject ( int left, int top, int right, int bottom)
                    ; //是否没和该矩形相交
                    public native boolean quickReject (Region rgn);  //是否没和该矩形相交

            //几个平移变换的方法
                    public void translate ( int dx, int dy)
                    public native void translate ( int dx, int dy, Region dst);
                    public void scale ( float scale) //hide
                    public native void scale ( float scale, Region dst);//hide
          */


    }

    /**
     * 用于绘制Region
     *
     * @param canvas 画布
     * @param region 要绘制的区域
     * @param paint  画笔
     */
    private void drawRegion(Canvas canvas, Region region, Paint paint) {
        //其实质就是把region分成无数个矩形，然后进行绘制，当把Paint的Style设置为Stroken时就可以看到中间区域的很多个rect
        RegionIterator iterator = new RegionIterator(region);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, paint);
        }
    }
}
